package com.fingard.dsp.bank.directbank.cbhb01;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.FtpSet;
import com.fingard.dsp.bank.directbank.bankInterface.IReceipt;
import com.fingard.dsp.bank.directbank.hxb02.util.SocketClient;
import com.fingard.dsp.bank.directbank.pab02.Util.api.utils.StringUtil;
import com.fingard.dsp.bank.reqrespobj.downloadreceipt.ReqQryReceipt;
import com.fingard.dsp.bank.reqrespobj.downloadreceipt.RetAtsReceipt;
import com.fingard.text.StringHelper;
import com.fingard.util.FtpUtil;
import com.fingard.util.SmbFileUtil;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;

import java.io.File;
import java.text.ParseException;
import java.util.*;

/**
 * created by slience on 2019/6/13
 */
public class CBHB01Receipt extends CBHB01Base implements IReceipt {
    @Override
    public RetAtsReceipt qryReceipt(ReqQryReceipt p_reqReceipt) throws Exception {

        RetAtsReceipt retAts = new RetAtsReceipt(p_reqReceipt.reqHeader);

        download(p_reqReceipt);

        retAts.respCode = "0";
        retAts.respInfo = "后台处理中";
        retAts.writeRetToATS();


        return retAts;
    }

    private void download(ReqQryReceipt p_reqReceipt) {
        List<Map<String, String>> mapList = queryReceiptDayBook(p_reqReceipt);
        int uploadcount = 0;

        if (null != mapList && mapList.size() > 0) {
            Iterator<Map<String, String>> iterator = mapList.iterator();
            List<Map<String, String>> needPushData = new ArrayList<Map<String, String>>(mapList.size());
            while (iterator.hasNext()) {
                Map<String, String> map = iterator.next();
                String vouchType = MapUtils.getString(map, "Vouch_Type");
                String printTaskId = MapUtils.getString(map, "PrintTaskId");
                String[] retValue = getDetailFilePath(vouchType, printTaskId);
                if (retValue[0].length() == 0) {
                    String filePath = parseFilePath(retValue[1]);
                    String serialNo = parseSerialNo(retValue[1]);
                    map.put("actCur", p_reqReceipt.actCur);
                    Map<String, Object> result = uploadFileToRemote(filePath, p_reqReceipt.actNum);
                    if (null != result) {
                        Integer uploadResult = MapUtils.getInteger(result, "uploadResult");
                        String uploadFilePath = MapUtils.getString(result, "uploadFilePath");
                        map.put("filePath", uploadFilePath);
                        map.put("serialNo", serialNo);
                        WriteBankLogLn("上传结果：" + uploadResult + " 上传文件路径:" + uploadFilePath);
                        if (uploadResult == 0) {
                            uploadcount++;
                            needPushData.add(map);
                        }
                    }
                } else {
                    WriteBankLogLn("凭证类型为" + vouchType + " 打印流水号为" + printTaskId + "获取明细文件失败,失败原因：" + retValue[1]);
                }
            }

            WriteBankLogLn("上传成功数量:" + uploadcount);
            pushReceiptToAts(needPushData, p_reqReceipt.actNum);

        } else {
            WriteBankLogLn("回单数据查询为空");
        }

    }

    private String parseSerialNo(String respInfo) {
        StringBuilder tmpSbMsg1 = new StringBuilder();
        XmlTextReader tmpBkReader = loadBankRespXmlReader(respInfo, tmpSbMsg1);
        String serialNo = null;
        try {
            String tmpRetCode = tmpBkReader.getFirstText("/CBHB/head/RespondCode");
            if ("000000".equals(tmpRetCode)) {
                if (tmpBkReader.read("/CBHB/body")) {
                    serialNo = tmpBkReader.readedXElement.getSingleText("HLOGN");
                }
            }
        } catch (Exception e) {
            WriteBankLogLn(e.getMessage());
        }
        return serialNo;
    }

    private void pushReceiptToAts(List<Map<String, String>> needPushData, String actNum) {
        StringBuilder json = new StringBuilder();
        json.append("transType=downloadreceipt&data={\"rows\":[");
        if (CollectionUtils.isNotEmpty(needPushData)) {
            String strValue = bankFront.getStrValueByFor("receiptDataCount", "");
            if (StringHelper.isNullOrEmpty(strValue)) {
                strValue = "500";
            }
            Integer receiptDataCount = Integer.valueOf(strValue);

            for (int i = 0; i < needPushData.size(); i++) {
                Map<String, String> data = needPushData.get(i);
                if ((i + 1) % receiptDataCount == 0 || i == needPushData.size() - 1) {
                    String[] retData = new String[0];
                    StringBuilder sendData = convertSendData(actNum, data);
                    json.append(sendData);
                    json.deleteCharAt(json.length() - 1);
                    json.append("]}");
                    try {
                        retData = sendToATS(json.toString());
                    } catch (Exception e) {
                        WriteBankLogLn(e.getMessage());
                    }
                    if (retData[0].length() == 0 && retData[1].equals("ok")) {
                        WriteBankLogLn("5.推送数据到ATS成功" + ((i + 1) % receiptDataCount > 0 ? (i + 1) % receiptDataCount : receiptDataCount) + "笔,请查看数据");
                    } else {
                        WriteBankLogLn("5.推送数据到ATS失败" + ((i + 1) % receiptDataCount > 0 ? (i + 1) % receiptDataCount : receiptDataCount) + "笔,请查看数据");
                    }
                    json = new StringBuilder();
                    json.append("transType=downloadreceipt&data={\"rows\":[");
                } else {
                    StringBuilder sendData = convertSendData(actNum, data);
                    json.append(sendData);
                }
            }
        }

    }

    private StringBuilder convertSendData(String actNum, Map<String, String> data) {
        StringBuilder json = new StringBuilder(500);
        try {
            String trade_date = Format.Date10Format.format(Format.Date8Format.parse(MapUtils.getString(data, "Trade_Date")));
            String payActNum = MapUtils.getString(data, "PayErAccNo");
            String oppActNum = MapUtils.getString(data, "PayEeAccNo");
            if (!StringUtil.isNull(actNum) && actNum.equals(oppActNum)) {
                payActNum = MapUtils.getString(data, "PayEeAccNo");
                oppActNum = MapUtils.getString(data, "PayErAccNo");
            }
            json.append("{");
            json.append("\"actNum\":\"" + payActNum + "\",");
            json.append("\"actCur\":\"" + MapUtils.getString(data, "actCur") + "\",");
            json.append("\"receiptCode\":\"" + MapUtils.getString(data, "PrintTaskId") + "\",");
            json.append("\"receiptType\":\"" + "" + "\",");
            json.append("\"receiptState\":\"" + "" + "\",");
            json.append("\"oppActName\":\"" + MapUtils.getString(data, "PayEeAccName") + "\",");
            json.append("\"oppActNum\":\"" + oppActNum + "\",");
            json.append("\"amount\":\"" + MapUtils.getString(data, "Amount") + "\",");
            json.append("\"moneyway\":\"" + "" + "\",");
            json.append("\"tranSeqNo\":\"" + MapUtils.getString(data, "serialNo") + "\",");
            json.append("\"tranDate\":\"" + trade_date + "\",");
            json.append("\"filePath\":\"" + MapUtils.getString(data, "filePath") + "\",");
            json.append("\"fileType\":\"1\"");
            json.append("},");
        } catch (ParseException e) {
            WriteBankLogLn(e.getMessage());
        }
        return json;
    }

    private Map<String, Object> uploadFileToRemote(String filePath, String payErAccNo) {
        Map<String, Object> result = null;
        try {
            result = uploadFile(filePath, payErAccNo);
        } catch (Exception e) {
            WriteBankLogLn(e.getMessage());
        }

        return result;
    }


    private Map<String, Object> uploadFile(String filePath, String payErAccNo) throws Exception {
        if (StringUtil.isNull(filePath)) {
            return null;
        }
        Map<String, Object> result = null;
        WriteBankLogLn("文件路径：" + filePath);
        WriteBankLogLn("文件名长度：" + "00" + filePath.length());
        String msg = "FILED3" + "00" + filePath.length() + filePath;
        WriteBankLogLn("请求下载报文:" + msg);
        String tmpStrRet = new String(SocketClient.sendInfo(msg.getBytes(getCharset()), 120 * 1000, bankFront.serverIP, Integer.valueOf(bankFront.signPort)));
        String resp = "";
        if (!StringUtil.isNull(tmpStrRet)) {
            resp = tmpStrRet.substring(0, 12 + filePath.length());
        }
        WriteBankLogLn("响应下载报文:" + resp);
        String respCode = resp.substring(6, 12);
        WriteBankLogLn("响应下载码：" + respCode);
        if ("000000".equals(respCode)) {
            result = new HashMap<String, Object>();
            int uploadResult = -1;
            String tmpByDate = Format.Date8Format.format(new Date());
            filePath = bankFront.bankReceiptMainDir + tmpByDate + "/" + "download" + "/" + filePath;
            WriteBankLogLn("文件下载路径：" + filePath);
            String ftpFilePath = "";
            tmpByDate = tmpByDate.substring(0, 6) + "/" + tmpByDate.substring(6, 8) + "/" + reqHeader.bankCode + "/" + payErAccNo + "/";
            if (!"false".equals(FGBiz.dspCenter.dspSet.receiptShareDir)) {
                if (new File(filePath).exists()) {
                    WriteBankLogLn("正在上传文件至共享目录:" + FGBiz.dspCenter.dspSet.receiptShareDir);
                    uploadResult = SmbFileUtil.smbUploading(filePath, tmpByDate, FGBiz.dspCenter.dspSet.receiptShareDir);
                }
            } else {
                //ftp服务
                FtpSet ftpSet2 = FGBiz.dspCenter.dspConfig.getReceiptFtpSet("atsReceipt");
                WriteBankLogLn("正在上传文件至ftp目录:" + ftpSet2.upDir);
                //上传ftp服务器的地址
                ftpFilePath = StringHelper.trimEndFileSp(ftpSet2.upDir) + "/" + tmpByDate;
                WriteBankLogLn("开始将回单" + filePath + "上传至" + ftpFilePath);
                //上传至ftp
                uploadResult = FtpUtil.ftpUploading(ftpSet2, filePath, ftpFilePath);
            }
            if (new File(filePath).exists()) {
                result.put("uploadFilePath", tmpByDate + new File(filePath).getName());
            } else {
                result.put("uploadFilePath", "");
            }
            result.put("uploadResult", uploadResult);
        }

        return result;
    }

    private String parseFilePath(String respInfo) {
        StringBuilder tmpSbMsg1 = new StringBuilder();
        XmlTextReader tmpBkReader = loadBankRespXmlReader(respInfo, tmpSbMsg1);
        String fileUrl = null;
        try {
            String tmpRetCode = tmpBkReader.getFirstText("/CBHB/head/RespondCode");
            if ("000000".equals(tmpRetCode)) {
                if (tmpBkReader.read("/CBHB/body")) {
                    fileUrl = tmpBkReader.readedXElement.getSingleText("PDFUrl");
                }
            }
        } catch (Exception e) {
            WriteBankLogLn(e.getMessage());
        }
        return fileUrl;
    }

    private String[] getDetailFilePath(String votchType, String printTaskId) {
        CBHB01Header cbhb01Header = new CBHB01Header();
        cbhb01Header.TransCode = "EDSQ02";
        cbhb01Header.ClientSeqno = getQryTransID();
        String[] tmpStrRet = new String[]{"", ""};
        try {
            XmlTextWriter xmlWriter = new XmlTextWriter();
            xmlWriter.autoFormat = false;
            writeCommonHeader(xmlWriter, cbhb01Header);
            xmlWriter.writeStartElement("body");
            xmlWriter.writeElementString("PRINTTASKID", printTaskId);
            xmlWriter.writeElementString("VOUCH_TYPE", votchType);
            xmlWriter.writeEndDocument();
            tmpStrRet = sendToBank(xmlWriter.toXmlString());
        } catch (Exception e) {
            WriteBankLogLn(e.getMessage());
        }
        return tmpStrRet;
    }


    private List<Map<String, String>> parseReqFileParam(String dayBookRet) {
        StringBuilder tmpSbMsg1 = new StringBuilder();
        XmlTextReader tmpBkReader = loadBankRespXmlReader(dayBookRet, tmpSbMsg1);
        int totalCount = 0;
        List<Map<String, String>> result = null;
        if (null != tmpBkReader) {
            try {
                String tmpRetCode = tmpBkReader.getFirstText("/CBHB/head/RespondCode");
                String totalRecord = tmpBkReader.getFirstText("/CBHB/head/RecordTotal");
                String bankSeqno = tmpBkReader.getFirstText("/CBHB/head/BankSeqno");
                String transCode = tmpBkReader.getFirstText("/CBHB/head/TransCode");

                if ("000000".equals(tmpRetCode)) {
                    totalCount = Integer.parseInt(totalRecord);
                    result = new ArrayList<Map<String, String>>(totalCount);
                    while (tmpBkReader.read("/CBHB/body/PrintTaskList/Record")) {
                        XElement tmpRecord = tmpBkReader.readedXElement;
                        Map<String, String> value = new HashMap<String, String>();

                        value.put("PrintTaskId", tmpRecord.getSingleText("PrintTaskId"));
                        value.put("Amount", tmpRecord.getSingleText("Amount"));
                        value.put("PayErAccNo", tmpRecord.getSingleText("PayErAccNo"));
                        value.put("PayErAccName", tmpRecord.getSingleText("PayErAccName"));
                        value.put("PayEeAccNo", tmpRecord.getSingleText("PayEeAccNo"));
                        value.put("PayEeAccName", tmpRecord.getSingleText("PayEeAccName"));
                        value.put("Trade_Date", tmpRecord.getSingleText("Trade_Date"));
                        value.put("Vouch_Type", tmpRecord.getSingleText("Vouch_Type"));
                        value.put("BankSeqno", bankSeqno);
                        value.put("TransCode", transCode);
                        result.add(value);
                    }

                }


            } catch (Exception e) {
                WriteBankLogLn(e.getMessage());
            }
        }
        return result;
    }


    private List<Map<String, String>> queryReceiptDayBook(ReqQryReceipt p_reqReceipt) {
        List<Map<String, String>> result = new ArrayList<Map<String, String>>();
        int currPage = 1;
        int totalCount = 0;
        int pageSize = Integer.parseInt(getBankConfig().getValueAsString("pageSize", "500"));
        do {
            try {
                Calendar tmpCalendarFrom = Calendar.getInstance();
                tmpCalendarFrom.setTime(p_reqReceipt.getDateFrom());

                Calendar tmpCalendarTo = Calendar.getInstance();
                tmpCalendarTo.setTime(p_reqReceipt.getDateTo());
                CBHB01Header cbhb01Header = new CBHB01Header();
                cbhb01Header.TransCode = "EDSQ01";
                cbhb01Header.ClientSeqno = getQryTransID();
                XmlTextWriter xmlWriter = new XmlTextWriter();
                xmlWriter.autoFormat = false;
                writeCommonHeader(xmlWriter, cbhb01Header, ((currPage - 1) * pageSize) + "", pageSize + "");
                xmlWriter.writeStartElement("body");
                xmlWriter.writeElementString("BeginDate", Format.Date8Format.format(tmpCalendarFrom.getTime()));
                xmlWriter.writeElementString("EndDate", Format.Date8Format.format(tmpCalendarTo.getTime()));
                xmlWriter.writeElementString("PageNo", currPage + "");
                xmlWriter.writeElementString("NumOfPage", pageSize + "");
          /*  if (!StringUtil.isNull(p_reqReceipt.actNum)) {
                xmlWriter.writeElementString("PayErAccNo", p_reqReceipt.actNum);
            }*/
                xmlWriter.writeEndDocument();
                String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());

                if (tmpStrRet[0].length() == 0) {
                    StringBuilder tmpSbMsg1 = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg1);
                    if (null != tmpBkReader) {
                        try {
                            String tmpRetCode = tmpBkReader.getFirstText("/CBHB/head/RespondCode");
                            String tmpRetInfo = tmpBkReader.getFirstText("/CBHB/head/RespondInfo");
                            String totalRecord = tmpBkReader.getFirstText("/CBHB/head/RecordTotal");
                            String bankSeqno = tmpBkReader.getFirstText("/CBHB/head/BankSeqno");
                            String transCode = tmpBkReader.getFirstText("/CBHB/head/TransCode");

                            if ("000000".equals(tmpRetCode)) {
                                totalCount = Integer.parseInt(totalRecord);
                                while (tmpBkReader.read("/CBHB/body/PrintTaskList/Record")) {
                                    XElement tmpRecord = tmpBkReader.readedXElement;
                                    Map<String, String> value = new HashMap<String, String>();

                                    value.put("PrintTaskId", tmpRecord.getSingleText("PrintTaskId"));
                                    value.put("Amount", tmpRecord.getSingleText("Amount"));
                                    value.put("PayErAccNo", tmpRecord.getSingleText("PayErAccNo"));
                                    value.put("PayErAccName", tmpRecord.getSingleText("PayErAccName"));
                                    value.put("PayEeAccNo", tmpRecord.getSingleText("PayEeAccNo"));
                                    value.put("PayEeAccName", tmpRecord.getSingleText("PayEeAccName"));
                                    value.put("Trade_Date", tmpRecord.getSingleText("Trade_Date"));
                                    value.put("Vouch_Type", tmpRecord.getSingleText("Vouch_Type"));
                                    value.put("BankSeqno", bankSeqno);
                                    value.put("TransCode", transCode);
                                    result.add(value);
                                }
                            } else {
                                WriteBankLogLn("分页查询第" + currPage + "页回单数据失败：" + tmpRetInfo);
                            }
                        } catch (Exception e) {
                            WriteBankLogLn(e.getMessage());
                        }
                    } else {
                        WriteBankLogLn("分页查询第" + currPage + "页回单数据失败：" + tmpSbMsg1);
                    }
                } else {
                    WriteBankLogLn("分页查询第" + currPage + "页回单数据失败：" + tmpStrRet[1]);
                }
            } catch (ParseException e) {
                WriteBankLogLn(e.getMessage());
            } catch (Exception e) {
                WriteBankLogLn(e.getMessage());
            }
            currPage++;
        } while (totalCount > (currPage - 1) * pageSize);
        return result;
    }


}
